#include "Vector3.h"

Vector3::Vector3() {
	x=y=z = 0;
}

Vector3::Vector3(const Vector3& v) {
	x = v.x;
	y = v.y;
	z = v.z;
}

Vector3::Vector3(const float vx, const float vy, const float vz/* = 0 */) {
	x = vx;
	y = vy;
	z = vz;
}

Vector3::~Vector3() {}

void Vector3::operator =(const Vector3 &v) {
	x = v.x;
	y = v.y;
	z = v.z;
}

Vector3 Vector3::operator *(const float scale) {
	return Vector3(x*scale, y*scale, z*scale);
}

Vector3 Vector3::operator +(const Vector3& v) {
	return Vector3(x+v.x, y + v.y, z + v.z);
}

Vector3 Vector3::operator +(const float a) {
	return Vector3(x+a, y + a, z + a);
}

Vector3 Vector3::operator -(const Vector3 &v) {
	return Vector3(x-v.x, y-v.y, z-v.z);
}

Vector3 &Vector3::operator +=(const Vector3 &v) {
	x+=v.x;
	y+=v.y;
	z+=v.z;
	return *this;//Seems to get around memory leak problems
}

Vector3& Vector3::operator -=(const Vector3 &v) {
	x-=v.x;
	y-=v.y;
	z-=v.z;
	return *this;
}

Vector3& Vector3::operator *=(const float scale) {
	x*=scale;
	y*=scale;
	z*=scale;
	return *this;
}

bool Vector3::operator<(const Vector3& v) {
	return (x < v.x && y < v.y && z < v.z);
}

bool Vector3::operator<=(const Vector3& v) {
	return (x <= v.x && y <= v.y && z <= v.z);
}

bool Vector3::operator>(const Vector3& v) {
	return (x > v.x && y > v.y && z > v.z);
}

bool Vector3::operator>=(const Vector3& v) {
	return (x >= v.x && y >= v.y && z >= v.z);
}

float Vector3::length() {
	return sqrt(x*x + y*y + z*z);
}

void Vector3::normalize() {
	/*float len = length();
	Vector3 v = Vector3(x,y,z)*(1.0f/len);
	x = v.x;
	y = v.y;
	z = v.z;*/
	float factor = 1.0f/length();
	x = x*factor;
	y = y*factor;
	z = z*factor;
}

Vector3 Vector3::crossProduct(const Vector3& v1, const Vector3& v2) {
	float a, b, c, d, e, f;
	
	a = v1.x;
	b = v1.y;
	c = v1.z;
	d = v2.x;
	e = v2.y;
	f = v2.z;
	
	Vector3 newVector;
	
	newVector.x = (b*f - c*e);
	newVector.y = (c*d - a*f);
	newVector.z = (a*e - b*d);
	
	return newVector;
}

float Vector3::dotProduct(const Vector3& v1, const Vector3& v2) {
	return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
}

ostream& operator << (ostream& os, const Vector3& v) {
	os << "(" << v.x << ", " << v.y << ", " << v.z << ")";
	return os;
}